#include "StdAfx.h"
#include "Sky.h"

VAMPIRE_NAMESPACE_BEGIN

void Sky::draw()
{
	begin();
	mpEffect->setTexture(mpCubeTex);

	UINT numPasses = mpEffect->begin();
	for (UINT passID = 0; passID < numPasses; ++passID)
	{
		mpEffect->beginPass(passID);
		Matrix44 worldMat = Camera::getMainCameraPtr()->getViewMatrix().getInverse();
		mpEffect->setTransformMatrix(Camera::getMainCameraPtr()->getViewProjMatrix());
		mpEffect->setEyePosition(Camera::getMainCameraPtr()->getPosition());
		mpEffect->setWorldMatrix(worldMat);
		mpEffect->commitChanges();
		mpBox->draw();
		mpEffect->endPass();
	}

	mpEffect->end();
	end();
}

void Sky::begin()
{
	gpDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
	gpDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
	gpDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
}

void Sky::end()
{
	gpDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
	gpDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
	gpDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
}

void Sky::setTexture( Texture* tex )
{
	mpCubeTex = tex;
}



void SkyBox::createSkyBox()
{
	Camera* cam = Camera::getMainCameraPtr();
	mSkyBoxSize = cam->getFarClipDistance() / 2 - 1;
	gpDevice->CreateVertexBuffer(
		mVertexCount * sizeof(SkyBoxVertex),
		D3DUSAGE_DYNAMIC,
		SkyBoxVertex::FVF,
		D3DPOOL_DEFAULT,
		&mpVertexBuffer,
		NULL);
	gpDevice->CreateIndexBuffer(
		mFaceCount * 3 * sizeof(WORD),
		D3DUSAGE_DYNAMIC,
		D3DFMT_INDEX16,
		D3DPOOL_DEFAULT,
		&mpIndexBuffer,
		NULL);

	mpVertexData = new SkyBoxVertex[mVertexCount];
	mpVertexBuffer->Lock(0, 0, (void**)&mpVertexData, D3DLOCK_DISCARD);

	mpVertexData[0] = SkyBoxVertex(-mSkyBoxSize, -mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[1] = SkyBoxVertex(-mSkyBoxSize,  mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[2] = SkyBoxVertex( mSkyBoxSize,  mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[3] = SkyBoxVertex( mSkyBoxSize, -mSkyBoxSize, -mSkyBoxSize);

	// fill in the back face vertex data
	mpVertexData[4] = SkyBoxVertex(-mSkyBoxSize, -mSkyBoxSize, mSkyBoxSize);
	mpVertexData[5] = SkyBoxVertex( mSkyBoxSize, -mSkyBoxSize, mSkyBoxSize);
	mpVertexData[6] = SkyBoxVertex( mSkyBoxSize,  mSkyBoxSize, mSkyBoxSize);
	mpVertexData[7] = SkyBoxVertex(-mSkyBoxSize,  mSkyBoxSize, mSkyBoxSize);

	// fill in the top face vertex data
	mpVertexData[8]  = SkyBoxVertex(-mSkyBoxSize, mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[9]  = SkyBoxVertex(-mSkyBoxSize, mSkyBoxSize,  mSkyBoxSize);
	mpVertexData[10] = SkyBoxVertex( mSkyBoxSize, mSkyBoxSize,  mSkyBoxSize);
	mpVertexData[11] = SkyBoxVertex( mSkyBoxSize, mSkyBoxSize, -mSkyBoxSize);

	// fill in the bottom face vertex data
	mpVertexData[12] = SkyBoxVertex(-mSkyBoxSize, -mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[13] = SkyBoxVertex( mSkyBoxSize, -mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[14] = SkyBoxVertex( mSkyBoxSize, -mSkyBoxSize,  mSkyBoxSize);
	mpVertexData[15] = SkyBoxVertex(-mSkyBoxSize, -mSkyBoxSize,  mSkyBoxSize);

	// fill in the left face vertex data
	mpVertexData[16] = SkyBoxVertex(-mSkyBoxSize, -mSkyBoxSize,  mSkyBoxSize);
	mpVertexData[17] = SkyBoxVertex(-mSkyBoxSize,  mSkyBoxSize,  mSkyBoxSize);
	mpVertexData[18] = SkyBoxVertex(-mSkyBoxSize,  mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[19] = SkyBoxVertex(-mSkyBoxSize, -mSkyBoxSize, -mSkyBoxSize);

	// fill in the right face vertex data
	mpVertexData[20] = SkyBoxVertex(mSkyBoxSize, -mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[21] = SkyBoxVertex(mSkyBoxSize,  mSkyBoxSize, -mSkyBoxSize);
	mpVertexData[22] = SkyBoxVertex(mSkyBoxSize,  mSkyBoxSize,  mSkyBoxSize);
	mpVertexData[23] = SkyBoxVertex(mSkyBoxSize, -mSkyBoxSize,  mSkyBoxSize);

	mpVertexBuffer->Unlock();


	mpIndexData =  new WORD[mFaceCount * 3];
	mpIndexBuffer->Lock(0, 0, (void**)&mpIndexData, D3DLOCK_DISCARD);

	mpIndexData[0] = 2; mpIndexData[1] = 1; mpIndexData[2] = 0;
	mpIndexData[3] = 3; mpIndexData[4] = 2; mpIndexData[5] = 0;

	// fill in the back face index data
	mpIndexData[6] = 6; mpIndexData[7]  = 5; mpIndexData[8]  = 4;
	mpIndexData[9] = 7; mpIndexData[10] = 6; mpIndexData[11] = 4;

	// fill in the top face index data
	mpIndexData[12] = 10; mpIndexData[13] =  9; mpIndexData[14] = 8;
	mpIndexData[15] = 11; mpIndexData[16] = 10; mpIndexData[17] = 8;

	// fill in the bottom face index data
	mpIndexData[18] = 14; mpIndexData[19] = 13; mpIndexData[20] = 12;
	mpIndexData[21] = 15; mpIndexData[22] = 14; mpIndexData[23] = 12;

	// fill in the left face index data
	mpIndexData[24] = 18; mpIndexData[25] = 17; mpIndexData[26] = 16;
	mpIndexData[27] = 19; mpIndexData[28] = 18; mpIndexData[29] = 16;

	// fill in the right face index data
	mpIndexData[30] = 22; mpIndexData[31] = 21; mpIndexData[32] = 20;
	mpIndexData[33] = 23; mpIndexData[34] = 22; mpIndexData[35] = 20;

	mpIndexBuffer->Unlock();
}

void SkyBox::draw()
{
	gpDevice->SetStreamSource(0, mpVertexBuffer, 0, sizeof(SkyBoxVertex)); 
	gpDevice->SetIndices(mpIndexBuffer);                             
	gpDevice->SetFVF(SkyBoxVertex::FVF);                              	
	gpDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mVertexCount, 0, mFaceCount);
}


const DWORD SkyBox::SkyBoxVertex::FVF = D3DFVF_XYZ;

VAMPIRE_NAMESPACE_END